As computers and the computer software executing on computers becomes more complex and powerful, performance analysis techniques have increased in importance for optimizing the performance and reliability of computer software. Profiling is one technique that has been found to be useful in connection with analyzing the performance of computer software.
Modern software applications are often object-oriented in nature, and are typically organized into a hierarchy of program entities that perform the various operations of the applications. Many software applications, for example, may contain at least one component, and each component may contain one or more classes. Furthermore, each class may contain one or more methods. With profiling, a tool commonly referred to as a profiler is used to capture events and other statistical information about program code being profiled in the software application. For example, a profiler may be used to capture information regarding memory and other resource usage for the purpose of identifying potential memory leaks, garbage collection problems, or other circumstances that may lead to excessive consumption of system resources. Additionally, the profiler may be used to capture information such as the time spent in various routines or methods, the number of instances created for certain classes, and the state of a call stack for the purpose of identifying particular sections of program code that perform sub-optimally. Profiling may be performed by adding special fragments of code to the application program code prior to compilation. The fragments of code added prior to compilation (often referred to as instrumenting or instrumentation) may enable monitoring or measuring of the performance of the application.
Alternatively, a runtime environment may support data collection capabilities to capture relevant profiling information for program code that does not have special fragments of code added prior to compilation.
Conventional profilers typically collect profile information at the method level, and often times this method level information is adequate for analyzing the performance of small software applications as these typically contain relatively few components and classes. For example, a person analyzing the performance of such small software applications may be able to manually extrapolate problems with the components and classes from the method level information by manually connecting the methods to the associated classes and components. But, using method level information captured by such profilers may present problems when conducting performance analysis on large software applications.
Much more complicated than small software applications, large software applications typically contain many components, classes, and methods. For example, a single instance of a large application server may load about 12,000 classes when started. Each class may contain several methods, and as such, the application server instance may load about 50,000 to about 100,000 methods when started. Other examples of large software applications that may contain many components, classes, and methods include native code database applications, messaging engines, and other enterprise applications.
Indeed, performance analysis of large software applications may be challenging with modern day profiling tools because of the larger number of components, classes, and methods, and also because the performance issues may not be localized to just a few methods. For instance, there may be larger scale performance issues associated with a few, or many, of the classes or components of the system, or with the interaction of the classes and components within the system. As a result, the method level information captured by conventional profilers may be inadequate for effectively analyzing the performance of such large software applications.
Specifically, the method level information provided by conventional profilers may be too granular to be useful when analyzing larger scale performance issues. Example, when analyzing the startup time and memory footprint of an application server, performance issues may not be localized to a single class or method or even to a few methods or classes. Indeed, when analyzing the memory footprint of an application server, the individual memory footprint of each class or method may not be meaningful. Rather, the performance issues of each method may contribute to the performance issues of their respective classes. Likewise, the performance issues of each class may contribute to the performance issues of their respective components. And, in the context of large programs such as application servers, manually mapping each of the potentially tens of thousands of methods to its associated component may quickly become intractable.
Therefore, a need exists in the art for an improved manner of profiling, and in particular, an improved manner of profiling large software applications.